package com.charlessong.unionpay.service;

import com.alibaba.fastjson.JSONObject;
import com.charlessong.unionpay.domain.AjaxResult;
import com.charlessong.unionpay.utils.HttpClient;
import com.charlessong.unionpay.utils.RSAUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author charles
 * @Date 2021/11/19
 */
@Slf4j
@Service("wx")
public class WxPayServiceImpl implements IPayService{
    @Override
    public AjaxResult requestPay(String tn) {
        String payUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/app";
        String mchId = "XXX";
        String serialNo = "XXXXX";

        Map<String, Object> formatMap = new HashMap<String, Object>();
        formatMap.put("appid", "appid");
        formatMap.put("mchid", mchId);
        //订单号每次需要修改
        formatMap.put("out_trade_no", String.valueOf(System.currentTimeMillis()));
        formatMap.put("description", "测试");
        formatMap.put("notify_url", "xxxxx/notify/wxpay");

        Map<String, Object> amountMap = new HashMap<String, Object>();
        amountMap.put("total", 1);
        amountMap.put("currency", "CNY");

        formatMap.put("amount", amountMap);

        String privateKey = "";
        String reqJson = JSONObject.toJSONString(formatMap);

        String sign = getToken("POST","/v3/pay/transactions/app",reqJson,mchId,serialNo,privateKey);

        log.info("========>>>>统一下单参数：\n{}",formatMap);
        log.info("========>>>>生成的令牌：\n{}",sign);



        HttpClient hc = new HttpClient(payUrl, 60000,60000);
        try {
            int status = hc.send(reqJson, "UTF-8",sign);
            System.out.println(hc.getResult());
            Map<String, Object> preMap = JSONObject.parseObject(hc.getResult());

            Map<String, Object> authMap = new HashMap<String, Object>();
            authMap.put("partnerid", mchId);
            authMap.put("appid", "xxxxx");
            authMap.put("timeStamp", System.currentTimeMillis()/1000);
            authMap.put("nonceStr", UUID.randomUUID().toString().replace("-", "").toString());
            authMap.put("prepayid", preMap.get("prepay_id"));
            authMap.put("package", "Sign=WXPay");

            String genSign=getSign(authMap,privateKey);
            log.info("========>>>>生成的令牌：\n{}",genSign);
            authMap.put("sign", genSign);


            JSONObject authCode=new JSONObject();
            authCode.put("authCode",authMap);
            return AjaxResult.success(authCode);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public static String getSign(Map<String, Object> authMap, String privateKey) {

        String appId = authMap.get("appid").toString();
        String timestamp = authMap.get("timeStamp").toString();
        String nonceStr = authMap.get("nonceStr").toString();
        String prepayid = authMap.get("prepayid").toString();
        String message = appId + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + prepayid + "\n";
        String signature = null;
        try {
            signature = RSAUtil.rsaSign(message, privateKey, "UTF-8", "RSA2");
        } catch (Exception e) {

        }
        return signature;
    }

    public static String getToken(String method, String url, String body, String mchId, String serialNo,String privateKey) {
        //32位随机字符串
        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "").toString();
        long timestamp = System.currentTimeMillis() / 1000;
        //生成签名支付串--加密前
        String message = buildMessage(method, url, timestamp, nonceStr, body);

        String signature = null;
        try {
            signature = RSAUtil.rsaSign(message, privateKey, "UTF-8", "RSA2");
        } catch (Exception e) {

        }
        return "mchid=\"" + mchId + "\","
                + "nonce_str=\"" + nonceStr + "\","
                + "timestamp=\"" + timestamp + "\","
                + "serial_no=\"" + serialNo + "\","
                + "signature=\"" + signature + "\"";
    }

    public static String buildMessage(String method, String canonicalUrl, long timestamp, String nonceStr, String body) {
        return method + "\n"
                + canonicalUrl + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + body + "\n";
    }
}
